import java.util.HashMap;

//  面题：HashMap的处理方式  ConcurrentHashMap线程安全 它们的区别
//      哈希表
//  虽然哈希表一直在和冲突做斗争，但在实际使用过程中，我们认为哈希表的冲突率是不高的，冲突个数是可控的，
//  也就是每个桶中的链表的长度是一个常数，所以，通常意义下，我们认为哈希表的插入/删除/查找时间复杂度是O(1) 。
//
//  散列表的负载因子定义：a=填入表中元素的个数/散列表中的长度
//  冲突无法避免
//闭散列：
//  1.开放定址法：   线性探测   二次探测
//开散列(开链法)：
//  2.数组+链表
//      注：链表的长度不会很长 控制在常数范围内  但
//          JDK1.8开始 当链表的长度超过8 并且数组长度要64 这个链表就会变成红黑树










public class HashPractice {

//    387. 字符串中的第一个唯一字符
//    1.
    public int firstUniqChar(String s) {
        if(s == null) return -1;
        int[] arrays = new int[26];
        for(int i =0; i<s.length(); i++) {
            char ch = s.charAt(i);
            arrays[ch-97]++;
        }
        for(int i = 0;i<s.length();i++){
            char ch = s.charAt(i);
            if(arrays[ch-97] == 1) {
                return i;
            }
        }
        return -1;
    }

//    2.哈希表方法
    public int firstUniqChar2(String s) {
        HashMap<Character,Integer> hashMap = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            hashMap.put(ch,hashMap.getOrDefault(ch,0)+1);
        }
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (hashMap.get(ch) == 1) {
                return i;
            }
        }
        return -1;
    }
}
